#include"./httplib.h"
#include"data.hpp"
#include"Deamon.hpp"

namespace aod{
#define WWW_ROOT "./wwwroot"
#define VIDEO_ROOT "/video/"
#define IMAGE_ROOT "/image/"
    TableVideo *tb_video=NULL;
    class Server
    {
    private:
        int _port;
        httplib::Server _srv;
    private:
        static void Insert(const httplib::Request &req,httplib::Response &rsp)
        {
 
            if(req.is_multipart_form_data())
            {
                if(!req.form.has_field("name")||!req.form.has_field("info")||!req.form.has_file("video")||!req.form.has_file("image"))
                {
                    rsp.status=400;
                    rsp.body=R"({"result":false,"reason":"上传视频格式错误"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
                //获取客户端req信息
                std::string name=req.form.get_field("name");
                std::string info=req.form.get_field("info");
                httplib::FormData video=req.form.get_file("video");
                httplib::FormData image=req.form.get_file("image");
                //序列化客户端信息在指定路径下存储数据
                std::string video_name=name;
                std::string video_info=info;
                std::string root=WWW_ROOT;
                std::string video_path=root+VIDEO_ROOT+video_name+video.filename;
                std::string image_path=root+IMAGE_ROOT+video_name+image.filename;
                std::cout<<video_path<<std::endl;
                std::cout<<image_path<<std::endl;
                if(FileUtil(video_path).ReadContent(video.content)==false)
                {
                    rsp.status=500;
                    rsp.body=R"({"result":false,"reason":"视频存储失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
                if(FileUtil(image_path).ReadContent(image.content)==false)
                {
                    rsp.status=500;
                    rsp.body=R"({"result":false,"reason":"图片存储失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
                //在数据库中添加对应信息
                Json::Value video_json;
                video_json["name"]=video_name;
                video_json["info"]=video_info;
                video_json["video"]=VIDEO_ROOT+video_name+video.filename;
                video_json["image"]=IMAGE_ROOT+video_name+image.filename;
                if(tb_video->Insert(&video_json)==false)
                {
                    rsp.status=500;
                    rsp.body=R"({"result":false,"reason":"数据库添加信息失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
                rsp.set_redirect("/",303);//新增完成后重定向回根页面301永久重定向，302临时重定向
                return;
            }
        }

        static void Delete(const httplib::Request &req,httplib::Response &rsp)
        {
            int video_id=std::stoi(req.matches[1]);
            Json::Value video;
            if(tb_video->SelectOne(video_id,&video)==false)
            {
                rsp.status=500;
                rsp.body=R"({"result":false,"reason":"数据库中没有找到对应视频"})";
                rsp.set_header("Content-Type","application/json");
                return;
            }
            std::string root=WWW_ROOT;
            std::string video_path=root+video["video"].asString();
            std::string image_path=root+video["image"].asString();
            if(FileUtil(video_path).Exists()==false)
            {
                rsp.status=500;
                rsp.body=R"({"result":false,"reason":"服务器中没有找到对应视频"})";
                rsp.set_header("Content-Type","application/json");
                return;
            }
            if(FileUtil(image_path).Exists()==false)
            {
                rsp.status=500;
                rsp.body=R"({"result":false,"reason":"服务器中没有找到对应图片"})";
                rsp.set_header("Content-Type","application/json");
                return;
            }
            remove(video_path.c_str());
            remove(image_path.c_str());
            if(tb_video->Delete(video_id)==false)
            {
                rsp.status=500;
                rsp.body=R"({"result":false,"reason":"删除数据库中数据失败"})";
                rsp.set_header("Content-Type","application/json");
                return;
            }
        }

        static void Update(const httplib::Request &req,httplib::Response &rsp)
        {
            int video_id=std::stoi(req.matches[1]);
            Json::Value video;
            if(JsonUtil::UnSerialize(req.body,&video)==false)//修改信息对面需要传递一个json格式数据
            {
                rsp.status=400;
                rsp.body=R"({"result":false,"reason":"反序列化失败,请传入json格式数据"})";
                rsp.set_header("Content-Type","application/json");
                return;
            }
            if(tb_video->Update(video_id,video)==false)
            {
                rsp.status=500;
                rsp.body=R"({"result":false,"reason":"跟新数据库信息失败"})";
                rsp.set_header("Content-Type","application/json");
                return;
            }
        }
        static void SelectOne(const httplib::Request &req,httplib::Response &rsp)
        {
            int video_id=std::stoi(req.matches[1]);
            Json::Value video;
            if(tb_video->SelectOne(video_id,&video)==false)
            {
                rsp.status=500;
                rsp.body=R"({"result":false,"reason":"找不到对应视频"})";
                rsp.set_header("Content-Type","application/json");
                return;
            }
            if(JsonUtil::Serialize(video,&rsp.body)==false)
            {
                rsp.status=500;
                rsp.body=R"({"result":false,"reason":"序列化失败"})";
                rsp.set_header("Content-Type","application/json");
                return;
            }
            rsp.set_header("Content-Type","application/json");
            return;
        }
        static void SelectAll(const httplib::Request &req,httplib::Response &rsp)
        {
            bool flag=true;//默查找所有视频信息
            if(req.has_param("search")==true)
            {
                flag=false;//转表为模糊查找；
            }
            Json::Value videos;
            std::string val=req.get_param_value("search");

            if(flag)
            {
                if(tb_video->SelectAll(&videos)==false)
                {
                    rsp.status=500;
                    rsp.body=R"({"result":false,"reason":"全部视频查询失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
            }
            else
            {
                if(tb_video->SelectLike(val,&videos)==false)
                {
                    rsp.status=500;
                    rsp.body=R"({"result":false,"reason":"模糊查询失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
            }
            JsonUtil::Serialize(videos,&rsp.body);
            rsp.set_header("Content-Type","application/json");
            return;
        }
    public:
        Server(int port):_port(port)
        {}
        bool RunModule()
        {
            tb_video=new TableVideo;
            //初始化数据管理模块，创建服务器数据保存目录
            FileUtil(WWW_ROOT).CreateDirectory();//匿名对象

            std::string root=WWW_ROOT;
            std::string real_video_root=root+VIDEO_ROOT;
            FileUtil(real_video_root).CreateDirectory();

            std::string real_image_root=root+IMAGE_ROOT;
            FileUtil(real_image_root).CreateDirectory();
            //初始化完成开始搭建服务器的服务
            //设置静态资源根目录
            _srv.set_mount_point("/",WWW_ROOT);
            //添加服务与请求的联系
            _srv.Post("/video",Insert);
            _srv.Delete("/video/(\\d+)",Delete);
            _srv.Put("/video/(\\d+)",Update);
            _srv.Get("/video/",SelectAll);
            _srv.Get("/video/(\\d+)",SelectOne);
            
            _srv.listen("0.0.0.0",_port);
            return true;
        }

    };
}